using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using HengTong.ViewModel._Admin.SysJobPositionVms;
using Microsoft.EntityFrameworkCore;
using TiaoTaoHelper.Extension.Guid;
using TiaoTaoHelper.Wtm.Models;
using UUIDNext;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;

namespace HengTong.ViewModel._Admin.FrameworkGroupVMs
{
    public class FrameworkGroupVm : BaseCRUDVM<SysGroup>
    {
        public override DuplicatedInfo<SysGroup> SetDuplicatedCheck()
        {
            var rv = CreateFieldsInfo(SimpleField(x => x.GroupName));
            rv.AddGroup(SimpleField(x => x.GroupCode));
            return rv;
        }

        public FrameworkGroupVm()
        {
            SetInclude(x => x.Organizations);
        }

        /// <summary>
        /// 组织机构列表
        /// </summary>
        [Display(Name = "组织机构")]
        public List<Guid?> SelectedOrganizationIds { get; set; }

        /// <summary>
        /// 管理者岗位名称
        /// </summary>
        public string ManagerJobPositionName { get; set; }

        /// <summary>
        /// 职员岗位名称
        /// </summary>
        public string EmployeeJobPositionName { get; set; }

        /// <summary>
        /// 上级部门
        /// </summary>
        private SysGroup ParentGroup { get; set; }

        protected override void InitVM()
        {
            SelectedOrganizationIds = Entity?.Organizations?.Select(x => x.OrgId).ToList() ?? [];
        }

        public override void Validate()
        {
            if (Entity.ParentId == null && string.IsNullOrWhiteSpace(Entity.GroupCode))
            {
                MSD.AddModelError("Entity.GroupCode", "部门编码不能为空");
                return;
            }

            if (!string.IsNullOrWhiteSpace(Entity.Manager)) Entity.Manager = null;
            if (Entity.ParentId != null && Entity.ParentId != Guid.Empty)
            {
                var parent = DC.Set<SysGroup>()
                    .AsNoTracking()
                    .FirstOrDefault(x => x.ID == Entity.ParentId);
                if (parent == null)
                {
                    MSD.AddModelError("Entity.ParentId", "上级部门不存在");
                    return;
                }

                ParentGroup = parent;
            }

            if (Wtm.ConfigInfo.AppSettings.TryGetValue("CustomGroupCode", out var customGroupCode) &&
                bool.TryParse(customGroupCode, out bool result) && result &&
                !string.IsNullOrWhiteSpace(Entity.GroupCode))
            {
                if (ParentGroup != null && !Entity.GroupCode.StartsWith(ParentGroup.GroupCode))
                {
                    MSD.AddModelError("Entity.GroupCode", "部门编码必须以上级部门编码开头");
                    return;
                }

                //编辑模式的去重需要排除自身
                var any = DC.Set<SysGroup>()
                    .Where(e => e.GroupCode == Entity.GroupCode)
                    .WhereIf(Entity.ID != Guid.Empty, e => e.ID != Entity.ID)
                    .Any();
                if (any)
                {
                    MSD.AddModelError("Entity.GroupCode", "部门编码已存在");
                    return;
                }
            }
            else
            {
                if (Entity.ParentId != null && Entity.ParentId != Guid.Empty)
                {
                    //系统自动生成编码
                    var max = DC.Set<SysGroup>()
                        .Where(e => e.ParentId == Entity.ParentId)
                        .OrderByDescending(e => e.Step)
                        .Select(e => e.Step)
                        .FirstOrDefault();
                    do
                    {
                        max += 1;
                        Entity.GroupCode = ParentGroup.GroupCode + max.ToString("00");
                        var any = DC.Set<SysGroup>()
                            .Where(e => e.GroupCode == Entity.GroupCode)
                            .WhereIf(Entity.ID != Guid.Empty, e => e.ID != Entity.ID)
                            .Any();
                        if (!any) break;
                    } while (true);

                    Entity.Step = max;
                }
            }
            //base.Validate();
        }

        public override void DoAdd()
        {
            base.DoAdd();
            Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait();
        }

        public override async Task DoAddAsync()
        {
            var transaction = DC.BeginTransaction();
            try
            {
                Entity.CreateBy = Wtm.LoginUserInfo?.ITCode;
                Entity.UpdateBy = Wtm.LoginUserInfo?.ITCode;
                Entity.CreateTime = DateTime.Now;
                Entity.UpdateTime = DateTime.Now;
                Entity.ID = Uuid.NewDatabaseFriendly(Database.SqlServer);
                if (Entity.ParentId != null && Entity.ParentId != Guid.Empty)
                {
                    var parent = await DC.Set<SysGroup>()
                        .AsNoTracking()
                        .FirstOrDefaultAsync(x => x.ID == Entity.ParentId);
                    if (parent == null)
                    {
                        MSD.AddModelError("Entity.ParentId", "上级部门不存在");
                        return;
                    }

                    Entity.Level = parent.Level + 1;
                }
                else
                {
                    Entity.Level = 0;
                }

                //如果岗位名称不为空, 则新增岗位
                if (!string.IsNullOrEmpty(ManagerJobPositionName))
                {
                    var vm = Wtm.CreateVM<SysJobPositionVm>();
                    vm.SelectedRolesIds = new List<Guid?>();
                    var role = await DC.Set<FrameworkRole>()
                        .AsNoTracking()
                        .FirstOrDefaultAsync(e => e.RoleCode == "101");
                    if (role != null) vm.SelectedRolesIds.Add(role.ID);
                    vm.Entity = new SysJobPosition
                    {
                        Name = ManagerJobPositionName,
                        GroupId = Entity.ID,
                        CreateBy = Wtm.LoginUserInfo?.ITCode,
                        UpdateBy = Wtm.LoginUserInfo?.ITCode,
                        CreateTime = DateTime.Now,
                        UpdateTime = DateTime.Now
                    };
                    await vm.DoAddAsync();
                    if (!vm.MSD.IsValid)
                    {
                        MSD.AddModelError(" ", vm.MSD.GetFirstError());
                        return;
                    }
                }

                if (SelectedOrganizationIds != null)
                {
                    Entity.Organizations = new List<SysGroupOrg>();
                    foreach (var id in SelectedOrganizationIds)
                    {
                        var middle = new SysGroupOrg()
                        {
                            ID = Uuid.NewDatabaseFriendly(Database.SqlServer),
                            GroupId = Entity.ID,
                            OrgId = id
                        };
                        Entity.Organizations.Add(middle);
                    }
                }

                if (!string.IsNullOrEmpty(EmployeeJobPositionName))
                {
                    var vm = Wtm.CreateVM<SysJobPositionVm>();
                    vm.SelectedRolesIds = new List<Guid?>();
                    var role = await DC.Set<FrameworkRole>()
                        .AsNoTracking()
                        .FirstOrDefaultAsync(e => e.RoleCode == "102");
                    if (role != null) vm.SelectedRolesIds.Add(role.ID);
                    vm.Entity = new SysJobPosition
                    {
                        Name = EmployeeJobPositionName,
                        GroupId = Entity.ID,
                        CreateBy = Wtm.LoginUserInfo?.ITCode,
                        UpdateBy = Wtm.LoginUserInfo?.ITCode,
                        CreateTime = DateTime.Now,
                        UpdateTime = DateTime.Now
                    };
                    await vm.DoAddAsync();
                    if (!vm.MSD.IsValid)
                    {
                        MSD.AddModelError(" ", vm.MSD.GetFirstError());
                        return;
                    }
                }

                await base.DoAddAsync();
                await Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant);
                await transaction.CommitAsync();
            }
            catch (Exception e)
            {
                MSD.AddModelError(" ", e.Message);
                await transaction.RollbackAsync();
            }
            finally
            {
                await transaction.DisposeAsync();
            }
        }

        public override async Task DoEditAsync(bool updateAllFields = false)
        {
            Entity.UpdateBy = Wtm.LoginUserInfo?.ITCode;
            Entity.UpdateTime = DateTime.Now;
            if (Entity.ParentId != null && Entity.ParentId != Guid.Empty)
            {
                var parent = await DC.Set<SysGroup>()
                    .AsNoTracking()
                    .FirstOrDefaultAsync(x => x.ID == Entity.ParentId);
                if (parent == null)
                {
                    MSD.AddModelError("Entity.ParentId", "上级部门不存在");
                    return;
                }

                Entity.Level = parent.Level + 1;
            }
            else
            {
                Entity.Level = 0;
            }

            if (SelectedOrganizationIds != null)
            {
                Entity.Organizations = new List<SysGroupOrg>();
                foreach (var item in SelectedOrganizationIds)
                {
                    var middle = new SysGroupOrg()
                    {
                        OrgId = item
                    };
                    Entity.Organizations.Add(middle);
                }
            }

            await base.DoEditAsync(updateAllFields);
            Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait();
        }

        public override async Task DoDeleteAsync()
        {
            await using var tran = DC.BeginTransaction();
            try
            {
                await base.DoDeleteAsync();
                await DC.Set<FrameworkUserGroup>()
                    .Where(x => x.GroupCode == Entity.GroupCode)
                    .ExecuteDeleteAsync();
                await DC.SaveChangesAsync();
                await tran.CommitAsync();
                await Wtm.RemoveUserCacheByGroup(Entity.GroupCode);
                await Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant);
            }
            catch
            {
                await tran.RollbackAsync();
            }
        }
    }
}